/*
 * wcserv.c
 *
 *  Created on: Mar 29, 2012
 *      Author: root
 */

#include	"unp.h"

int
main(int argc, char **argv)
{
	int					listenfd, connfd;
	pid_t				childpid;
	socklen_t			clilen;
	struct sockaddr_in	cliaddr, servaddr;
	void				sig_chld(int);
	ssize_t			    n;
	char			    buf[MAXLINE];
	char 				*str;
	char 				str1[MAXLINE];
	char 				str2[MAXLINE];
	char 				str3[MAXLINE];
	int 				cmp, wcount, lcount, bcount, s_wcount, s_bcount ;

	const int on = 1;
	cmp = wcount = lcount = bcount = s_wcount = s_bcount = 0;

	listenfd = Socket(AF_INET, SOCK_STREAM, 0);

	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family      = AF_INET;
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servaddr.sin_port        = htons(SERV_PORT);
	Setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
	Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));

	Listen(listenfd, LISTENQ);

	Signal(SIGCHLD, sig_chld);	/* must call waitpid() */

	for ( ; ; ) {
		clilen = sizeof(cliaddr);
		if ( (connfd = accept(listenfd, (SA *) &cliaddr, &clilen)) < 0) {
			if (errno == EINTR)
				continue;		/* back to for() */
			else
				err_sys("accept error");
		}

		if ( (childpid = Fork()) == 0) {	/* child process */
			Close(listenfd);	/* close listening socket */
			while ((n = Readline(connfd, buf, MAXLINE)) > 0){

				cmp = strcmp(buf, ".\n");
				if(cmp==0){
					strcpy(str1, "Byte Counts : %d   ");
					sprintf(str1, str1, s_bcount);
					strcpy(str2, "Word Counts : %d   ");
					sprintf(str2,str2,s_wcount);
					strcat(str1, str2);
					strcpy(str3, "Line Counts : %d\n");
					sprintf(str3,str3,lcount);
					strcat(str1, str3);
					Writen(connfd, str1, strlen(str1));
					exit(0);
				}

				Fputs(buf, stdout);
				lcount++;
				bcount = n;
				wcount = 0;

				str = strtok(buf, " ");
				while(str != NULL)
				{
					wcount++;
					s_wcount++;
					str = strtok(NULL, " ");
				}
				bcount -= wcount;
				s_bcount += bcount;

				printf("Word Counts : %d\n", wcount);
				printf("Byte Counts : %d\n", bcount);
				printf("Line Counts : %d\n", lcount);

				strcpy(str1, "Byte Counts : %d   ");
				sprintf(str1, str1, bcount);
				strcpy(str2, "Word Counts : %d\n");
				sprintf(str2,str2,wcount);
				strcat(str1, str2);
				printf("%s",str1);
				Writen(connfd, str1, strlen(str1));
			}
			exit(0);
		}
		Close(connfd);			/* parent closes connected socket */
	}
}

void sig_chld(int signo)
{
  pid_t pid;
  int stat;

  while( (pid = waitpid ( -1, &stat, WNOHANG)) > 0 )
    fprintf(stderr,"child %d terminated signo %d\n",pid,signo);  /* not recommended to have a print here
						    but this does show what's happening */
  return;

}
